package com.gxa.eshops.portal.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.gxa.eshops.portal.entity.domain.Goods;
import com.gxa.eshops.portal.mapper.GoodsMapper;
import com.gxa.eshops.portal.service.GoodsService;
import com.gxa.eshps.cores.exception.BusinessException;
import com.gxa.eshps.cores.exception.ExceptionCode;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.Objects;
import java.util.UUID;
import java.util.concurrent.TimeUnit;
/**
 * @program: IntelliJ IDEA
 * @description:
 * @author: Mr.Wang
 * @create: 2022-07-08 09:47
 **/
@Service
@Transactional(rollbackFor = Throwable.class)
public class GoodsServiceImpl extends ServiceImpl<GoodsMapper, Goods> implements GoodsService {
    @Autowired
    private RedisTemplate<String ,Object> redisTemplate;

    private static final String GOODS_NAME = "kill:";

    private static final String LOCK = "LOCK:";

    @Override
    public  Boolean secondKill(Long id) throws BusinessException {
        ValueOperations<String, Object> opsForValue = redisTemplate.opsForValue();
        //加锁redis:set name value nx,声明成功表示成功加锁
        //传递4个参数,保证操作的原子性
        String value = UUID.randomUUID().toString().replaceAll("-", "");
        Boolean absent = opsForValue.setIfAbsent(LOCK + id, value, 5, TimeUnit.SECONDS);
        //如果获取锁失败
        if (Boolean.FALSE.equals(absent)){
            return false;
        }
        //获取商品数量
        Object num = opsForValue.get(GOODS_NAME + id);
        //数据校验
        if (num == null) {
            throw new BusinessException(ExceptionCode.NULL_GOODS);
        }
        if (Integer.parseInt(num.toString()) <= 0){
            return false;
        }
        //满足条件,商品减1
        opsForValue.decrement(GOODS_NAME + id);
        int num2 = Integer.parseInt(num.toString())-1;
        System.out.println("剩余商品:"+num2);
        //删除锁,谁加锁,谁删除
        if (Objects.equals(opsForValue.get(LOCK + id), value)){
            redisTemplate.delete(LOCK + id);
        }
        return true;
    }

}
